﻿using System;
using System.Linq;
using System.Threading;

namespace HmmmIDE.Debug
{
    public static class DebugService
    {
        public static int PC { get; set; }
        public static short[] Memory { get; set; }
        public static Register[] Registers { get; set; }
        public delegate void OnIORequested(object sender, TerminalEventArgs e);
        public delegate void OnInputRequested(object sender, EventArgs e);
        public static event OnIORequested OutputRequested;
        public static event OnInputRequested InputRequested;
        public static bool ShouldStop { get; set; }
        public static string IOValue { get; set; }

        public static AutoResetEvent _WaitForEnter = new AutoResetEvent(false);

        public static void Initialize()
        {
            Memory = new short[256];
            Registers = new Register[16];
            for (int i = 0; i < 16; i++)
                Registers[i] = new Register(i);

            PC = 0; // reset PC
            ShouldStop = true;
        }
        public static void Write(string text)
        {
            //Debug.WriteLine(text);
            TerminalEventArgs e = new TerminalEventArgs(text);
            OutputRequested(typeof(DebugService), e);
        }

        public static void Write(short value)
        {
            //Debug.WriteLine(value);
            TerminalEventArgs e = new TerminalEventArgs(value.ToString());
            OutputRequested(typeof(DebugService), e);
        }

        public static short Read()
        {
            InputRequested(typeof(DebugService), EventArgs.Empty);
            _WaitForEnter.WaitOne();
            return short.Parse(IOValue);
        }

        public static Register GetRegisterByName(string name)
        {
            return Registers.Where(element => element.RegisterNumber.ToString() == name.Substring(1)).ElementAt(0);
        }

        public class TerminalEventArgs : EventArgs
        {
            public string Value { get; set; }
            public TerminalEventArgs(string value)
            {
                this.Value = value;
            }
        }
    }
}
